﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Xml.Linq;

namespace Update.Servers.Github
{
    /// <summary>
    /// GitHub服务器实现
    /// </summary>
    public class GitHubServer : IUpdateServer
    {
        private string owner;
        private string repo;
        private string accessToken;
        private bool useRelease = true;
        private string branch = "main";
        private WebClient webClient;
        private string serverVersion;
        private string downloadUrl;
        
        public bool SupportsChangelog => true;
        
        public GitHubServer()
        {
            webClient = new WebClient();
            webClient.Encoding = Encoding.UTF8;
        }
        
        public void Initialize(XElement config)
        {
            if (config == null)
                throw new ArgumentNullException(nameof(config));
                
            // 获取仓库信息
            owner = config.Element("Owner")?.Value;
            repo = config.Element("Repo")?.Value;
            accessToken = config.Element("AccessToken")?.Value ?? "";
            useRelease = bool.Parse(config.Element("UseRelease")?.Value ?? "true");
            branch = config.Element("Branch")?.Value ?? "main";
            
            if (string.IsNullOrEmpty(owner) || string.IsNullOrEmpty(repo))
                throw new ArgumentException("未指定GitHub仓库信息");
                
            // 设置认证头
            if (!string.IsNullOrEmpty(accessToken))
            {
                webClient.Headers.Add("Authorization", $"token {accessToken}");
            }
            
            // 设置User-Agent
            webClient.Headers.Add("User-Agent", "UpdateApp");
        }
        
        public string GetServerVersion()
        {
            try
            {
                if (useRelease)
                {
                    return GetVersionFromRelease();
                }
                else
                {
                    return GetVersionFromBranch();
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"获取GitHub版本失败: {ex.Message}");
            }
        }
        
        private string GetVersionFromRelease()
        {
            string apiUrl = $"https://api.github.com/repos/{owner}/{repo}/releases/latest";
            
            // 发送请求获取最新版本
            string response = webClient.DownloadString(apiUrl);
            
            // 简单解析JSON响应，提取版本信息
            // 格式示例: {"tag_name":"v1.0.0",...}
            int tagNameIndex = response.IndexOf("\"tag_name\"");
            if (tagNameIndex > 0)
            {
                int valueStart = response.IndexOf(":", tagNameIndex) + 1;
                int valueEnd = response.IndexOf(",", valueStart);
                string tagName = response.Substring(valueStart, valueEnd - valueStart).Trim(' ', '"');
                serverVersion = tagName.TrimStart('v');
                
                // 尝试找到下载URL
                int browserDownloadUrlIndex = response.IndexOf("\"browser_download_url\"");
                if (browserDownloadUrlIndex > 0)
                {
                    valueStart = response.IndexOf(":", browserDownloadUrlIndex) + 1;
                    valueEnd = response.IndexOf(",", valueStart);
                    if (valueEnd < 0) valueEnd = response.IndexOf("}", valueStart);
                    downloadUrl = response.Substring(valueStart, valueEnd - valueStart).Trim(' ', '"');
                }
                
                return serverVersion;
            }
            
            throw new Exception("无法从GitHub响应中解析版本信息");
        }
        
        private string GetVersionFromBranch()
        {
            // 从branch中的version.txt获取版本信息
            string versionUrl = $"https://api.github.com/repos/{owner}/{repo}/contents/version.txt?ref={branch}";
            
            // 发送请求获取版本文件内容
            string response = webClient.DownloadString(versionUrl);
            
            // 提取content字段（Base64编码的内容）
            int contentIndex = response.IndexOf("\"content\"");
            if (contentIndex > 0)
            {
                int valueStart = response.IndexOf(":", contentIndex) + 1;
                int valueEnd = response.IndexOf(",", valueStart);
                if (valueEnd < 0) valueEnd = response.IndexOf("}", valueStart);
                string encodedContent = response.Substring(valueStart, valueEnd - valueStart).Trim(' ', '"');
                
                // 处理可能的转义字符
                encodedContent = encodedContent.Replace("\\n", "");
                
                // Base64解码
                byte[] bytes = Convert.FromBase64String(encodedContent);
                serverVersion = Encoding.UTF8.GetString(bytes).Trim();
                
                return serverVersion;
            }
            
            throw new Exception("无法从GitHub分支中获取版本信息");
        }
        
        public string DownloadUpdatePackage(string version, string savePath, Action<int,double, string> progressCallback)
        {
            try
            {
                // 确定更新包保存路径
                string updatePackagePath = Path.Combine(savePath, $"update_{version}.zip");
                
                // 确定更新包URL
                string updateUrl;
                if (!string.IsNullOrEmpty(downloadUrl) && downloadUrl.EndsWith(".zip"))
                {
                    updateUrl = downloadUrl;
                }
                else
                {
                    // 尝试从发布或仓库中下载
                    if (useRelease)
                    {
                        updateUrl = $"https://github.com/{owner}/{repo}/releases/download/v{version}/update_{version}.zip";
                    }
                    else
                    {
                        updateUrl = $"https://github.com/{owner}/{repo}/archive/refs/heads/{branch}.zip";
                    }
                }
                
                progressCallback?.Invoke(35, 0, $"正在从GitHub下载更新包: {updateUrl}");
                
                // 设置下载进度事件
                webClient.DownloadProgressChanged += (s, e) => {
                    progressCallback?.Invoke(35 + e.ProgressPercentage / 2, 0, $"下载更新包: {e.ProgressPercentage}%");
                };
                
                // 下载文件
                webClient.DownloadFile(new Uri(updateUrl), updatePackagePath);
                
                progressCallback?.Invoke(55, 0, "更新包下载完成");
                
                return updatePackagePath;
            }
            catch (Exception ex)
            {
                throw new Exception($"从GitHub下载更新包失败: {ex.Message}");
            }
        }
        
        public string GetChangelog(string version)
        {
            try
            {
                string changelogContent = "";
                
                if (useRelease)
                {
                    // 从release中获取更新日志
                    string apiUrl = $"https://api.github.com/repos/{owner}/{repo}/releases/tags/v{version}";
                    
                    // 发送请求获取release信息
                    string response = webClient.DownloadString(apiUrl);
                    
                    // 提取body字段（更新日志）
                    int bodyIndex = response.IndexOf("\"body\"");
                    if (bodyIndex > 0)
                    {
                        int valueStart = response.IndexOf(":", bodyIndex) + 1;
                        int valueEnd = response.IndexOf("\"", valueStart + 2);
                        if (valueEnd > valueStart)
                        {
                            changelogContent = response.Substring(valueStart, valueEnd - valueStart).Trim(' ', '"');
                            // 处理转义字符
                            changelogContent = changelogContent.Replace("\\r\\n", "\r\n").Replace("\\n", "\n");
                        }
                    }
                }
                else
                {
                    // 从仓库中获取changelog.md文件
                    string changelogUrl = $"https://api.github.com/repos/{owner}/{repo}/contents/changelog.md?ref={branch}";
                    
                    // 发送请求获取更新日志内容
                    string response = webClient.DownloadString(changelogUrl);
                    
                    // 提取content字段（Base64编码的内容）
                    int contentIndex = response.IndexOf("\"content\"");
                    if (contentIndex > 0)
                    {
                        int valueStart = response.IndexOf(":", contentIndex) + 1;
                        int valueEnd = response.IndexOf(",", valueStart);
                        if (valueEnd < 0) valueEnd = response.IndexOf("}", valueStart);
                        string encodedContent = response.Substring(valueStart, valueEnd - valueStart).Trim(' ', '"');
                        
                        // 处理可能的转义字符
                        encodedContent = encodedContent.Replace("\\n", "");
                        
                        // Base64解码
                        byte[] bytes = Convert.FromBase64String(encodedContent);
                        changelogContent = Encoding.UTF8.GetString(bytes);
                    }
                }
                
                return changelogContent;
            }
            catch (Exception ex)
            {
                return $"获取更新日志失败: {ex.Message}";
            }
        }
        
        public void Dispose()
        {
            webClient?.Dispose();
        }
    }
} 